package cn.org.seventh.web.common;

import java.util.Locale;
import java.util.Properties;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.util.WebUtils;

/**
 * 实现了spring的地区解析接口 增强了原有spring自带的解析器 该类综合了请求参数 http头 session和cookie
 * 这几种方式的地区信息检查 优先级为固定地区信息>session>cookie>http头 该类应作为基础配置
 * 
 * @author Seventh
 * 
 */
public class CustomLocaleResolver implements LocaleResolver {
	private Properties viewDir = new Properties();
	private String defaultViewDir = "/WEB-INF/";
	private SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver() {
		public Locale resolveLocale(HttpServletRequest request) {
			Locale locale = (Locale) WebUtils.getSessionAttribute(request,
					LOCALE_SESSION_ATTRIBUTE_NAME);
			return locale;
		}
	};
	private CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver() {
		public Locale resolveLocale(HttpServletRequest request) {
			// Check request for pre-parsed or preset locale.
			Locale locale = (Locale) request
					.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
			if (locale != null) {
				return locale;
			}

			// Retrieve and parse cookie value.
			Cookie cookie = WebUtils.getCookie(request, getCookieName());
			if (cookie != null) {
				locale = StringUtils.parseLocaleString(cookie.getValue());
				if (logger.isDebugEnabled()) {
					logger.debug("Parsed cookie value [" + cookie.getValue()
							+ "] into locale '" + locale + "'");
				}
				if (locale != null) {
					request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, locale);
					return locale;
				}
			}

			return locale;
		}
	};
	private AcceptHeaderLocaleResolver acceptHeaderLocaleResolver = new AcceptHeaderLocaleResolver();
	private FixedLocaleResolver fixedLocaleResolver = new FixedLocaleResolver();
	private boolean fixed = false;

	public Locale resolveLocale(HttpServletRequest request) {
		if (fixed) {
			return fixedLocaleResolver.resolveLocale(request);
		} else {
			if (null != sessionLocaleResolver.resolveLocale(request)) {
				return sessionLocaleResolver.resolveLocale(request);
			} else if (null != cookieLocaleResolver.resolveLocale(request)) {
				return cookieLocaleResolver.resolveLocale(request);
			} else {
				return acceptHeaderLocaleResolver.resolveLocale(request);
			}
		}
	}

	public void setLocale(HttpServletRequest request,
			HttpServletResponse response, Locale locale) {
		sessionLocaleResolver.setLocale(request, response, locale);
		cookieLocaleResolver.setLocale(request, response, locale);
	}

	public boolean isFixed() {
		return fixed;
	}

	public void setFixed(boolean fixed) {
		this.fixed = fixed;
	}

	public SessionLocaleResolver getSessionLocaleResolver() {
		return sessionLocaleResolver;
	}

	public CookieLocaleResolver getCookieLocaleResolver() {
		return cookieLocaleResolver;
	}

	public void setCookieDomain(String cookieDomain) {
		cookieLocaleResolver.setCookieDomain(cookieDomain);
	}

	public void setCookieMaxAge(int cookieMaxAge) {
		cookieLocaleResolver.setCookieMaxAge(cookieMaxAge);
	}

	public void setCookieName(String cookieName) {
		cookieLocaleResolver.setCookieName(cookieName);
	}

	public void setCookiePath(String cookiePath) {
		cookieLocaleResolver.setCookiePath(cookiePath);
	}

	public void setCookieSecure(boolean cookieSecure) {
		cookieLocaleResolver.setCookieSecure(cookieSecure);
	}

	public void setDefaultLocale(Locale defaultLocale) {
		fixedLocaleResolver.setDefaultLocale(defaultLocale);
	}

	public Properties getViewDir() {
		return viewDir;
	}

	public void setViewDir(Properties viewDir) {
		this.viewDir = viewDir;
	}

	public String getDefaultViewDir() {
		return defaultViewDir;
	}

	public void setDefaultViewDir(String defaultViewDir) {
		this.defaultViewDir = defaultViewDir;
	}

	public String getViewDir(HttpServletRequest request) {
		Locale locale = resolveLocale(request);
		if (null == locale) {
			return getDefaultViewDir();
		} else {
			return getViewDir().getProperty(locale.toString(),
					getDefaultViewDir());
		}
	}

}
